package graph;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @author AutumnWhisper
 * 回顾离散数学
 */
public class Node<V> {
    int id;//编号
    //顶点存储的值
    V value;
    //入度
    int in;
    //出度
    int out;
    //直接可达结点表:顶点V的所有相邻顶点的集合.====直接邻居
    ArrayList<Node<V>> nexts;
    //存储以该节点为起点的有向边。
    ArrayList<Edge<V>> edges;

    //初始化默认顶点为孤立点
    public Node(int id,V value) {
        this.id = id;
        this.value = value;
        this.in = 0;
        this.out = 0;
        this.nexts = new ArrayList<>();
        this.edges = new ArrayList<>();
    }
    public int getId() {
        return id;
    }
    public V getValue() {
        return value;
    }
    public V setValue(V value) {
        V oldVal = this.value;
        this.value = value;
        return oldVal;
    }
    public int getIn(){
        return in;
    }
    public int getOut(){
        return out;
    }
    //提供当前顶点的邻接顶点列表（不可修改）
    public List<Node<V>> getNexts(){
        return Collections.unmodifiableList(nexts);
    }
    //提供以当前结点为顶点的关联边数。
    public List<Edge<V>> getEdges(){
        return Collections.unmodifiableList(edges);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;
        Node<?> node = (Node<?>) obj;

        return id == node.id &&
                in == node.in &&
                out == node.out &&
                (value != null ? value.equals(node.value) : node.value == null) &&
                nexts.equals(node.nexts) &&
                edges.equals(node.edges);
    }

    @Override
    public int hashCode() {
        int result = Integer.hashCode(id);
        result = 31 * result + (value != null ? value.hashCode() : 0);
        result = 31 * result + Integer.hashCode(in);
        result = 31 * result + Integer.hashCode(out);
        result = 31 * result + nexts.hashCode();
        result = 31 * result + edges.hashCode();
        return result;
    }
    void addNeighbor(Node<V> neighbor){
        nexts.add(neighbor);
        this.out++;
        neighbor.in++;
    }
    void addEdge(Edge<V> edge){
        edges.add(edge);
    }
}
